package com.pengpeng.sheepfoldmall.product.feign;

import com.pengpeng.common.to.SkuReductionTo;
import com.pengpeng.common.to.SpuBoundTo;
import com.pengpeng.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * 调用优惠服务的客户端
 */
@FeignClient("sheepfold-coupon")  //标注要调用的远程接口的服务名称
public interface CouponFeignClient {

    /**
     * 保存spu的积分信息
     *
     * 微服务远程调用过程（以此次调用远程优惠服务的saveSpuBound方法为例）
     *      1.首先先保证两个服务的主启动类上都标注了 @EnableDiscoveryClient 以供服务注册中心发现
     *      2.主程序（商品服务）上标注了 @EnableFeignClients 注解开启远程调用功能
     *      3.编写远程调用的客户端接口，并标注@FeignClient("sheepfold-coupon") 注解，以供注册中心知道你要远程调用的是哪个微服务
     *      4.在此接口中编写具体要远程调用的方法
     *          @PostMapping("/coupon/spubounds/save")
     *          R saveSpuBound(@RequestBody SpuBoundTo spuBoundTo);
     *      5.接口的方法参数位置标注 @RequestBody 注解是为了将传输数据转换为json
     *      6.服务注册中心找到该服务的位置，并调用该方法，并将传输的json数据放到形参位置
     *      7.对方服务接收到这次请求后，将此json数据转为对应格式（这里是转换为SpuBoundsEntity），接着对方服务就处理此次请求，并将请求结果层层返回。
     *          public R save(@RequestBody SpuBoundsEntity spuBounds){ ... };
     *
     * 问题：
     *      以往我们图方便，都会直接将对方服务的某个方法的签名直接粘贴到主服务的远程调用接口中以保证路径以及参数的一致性，但此次我们并没有这样做，而是：
     *          远程服务Controller：
     *              @PostMapping("/coupon/spubounds/save")
     *              public R save(@RequestBody SpuBoundsEntity spuBounds){ ... };
     *          主服务Feign接口：
     *              @PostMapping("/coupon/spubounds/save")
     *              R saveSpuBound(@RequestBody SpuBoundTo spuBoundTo);
     *      那这样会不会导致对方服务接受此次请求数据时出现错误或没有接收到呢？
     *
     * 答（总结）：
     *      只要json数据模型是兼容的（属性是一一对应的），双方服务就无需使用同一个to（同一个类型）
     *
     * @param spuBoundTo
     * @return
     */
    @PostMapping("/coupon/spubounds/save")
    R saveSpuBound(@RequestBody SpuBoundTo spuBoundTo);

    /**
     * 保存sku的优惠、满减等详细信息
     */
    @PostMapping("/coupon/skufullreduction/saveSkuReductionInfo")
    R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);
}
